package com.itany.corejava.code16_反射;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

/**
 * @author MissChen
 * @version 1.0
 * @date 2023 年12月18日 13:33
 */
public class Test03_Constructor {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        User user = new User();
        Class c = user.getClass();
        // 1.获取当前类中的所有public修饰的构造方法
        Constructor[] constructors = c.getConstructors();
        System.out.println(Arrays.toString(constructors));


        // 2.获取当前类中的所有的构造方法
        Constructor[] constructors2 = c.getDeclaredConstructors();
        System.out.println(Arrays.toString(constructors2));


        // 3.根据传递的方法参数不同，返回对应的由public修饰的构造方法
        // 这个方法参数一个Class类型的可变长参数
        Constructor constructor = c.getConstructor();
        System.out.println(constructor);

        //由于private修饰的，无法获取的，有异常
        // constructor=c.getConstructor(String.class);
        // System.out.println(constructor);

        constructor = c.getConstructor(String.class, String.class);
        System.out.println(constructor);


        // 4.根据传递的方法参数不同，返回对应的构造方法，这个方法参数一个Class类型的可变长参数
        Constructor declaredConstructor = c.getDeclaredConstructor(String.class);
        System.out.println(declaredConstructor);

        //通过反射来调用指定的构造创建对应的对象
        User user1 = (User) constructor.newInstance("admin", "123");
        System.out.println(user1);

        //由于当前调用的构造是被private修饰的，外部无法访问，因为报错
        // 如果想要使用该构造创建对象，必须破坏原有的封装规则，使得private失效
        // setAccessible(true)：取消权限控制，使得private失效，破坏原有的封装原则

        declaredConstructor.setAccessible(true);
        User user2 = (User) declaredConstructor.newInstance("alice");
        System.out.println(user2);


    }
}
